package com.qujia.station.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.qujia.common.constant.UserConstants;
import com.qujia.common.core.domain.entity.SysRole;
import com.qujia.common.core.domain.entity.SysUser;
import com.qujia.common.core.domain.model.LoginUser;
import com.qujia.common.core.page.PageDomain;
import com.qujia.common.core.page.TableSupport;
import com.qujia.common.core.redis.RedisCache;
import com.qujia.common.enums.ErrorCode;
import com.qujia.common.exception.CustomException;
import com.qujia.common.utils.SecurityUtils;
import com.qujia.common.utils.sql.SqlUtil;
import com.qujia.station.domain.Station;
import com.qujia.station.domain.StationOillGun;
import com.qujia.station.domain.vo.GunVo;
import com.qujia.station.domain.vo.StaffVO;
import com.qujia.station.mapper.StaffMapper;
import com.qujia.station.service.IStaffService;
import com.qujia.station.service.IStationService;
import com.qujia.system.domain.SysAgent;
import com.qujia.system.mapper.SysDictDataMapper;
import com.qujia.system.mapper.SysUserMapper;
import com.qujia.system.service.ISysAgentService;
import com.qujia.system.service.ISysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class StaffServiceImpl implements IStaffService {

    public static final String DIC_TYPE_STAFF_SETTING = "staff_setting";
    public static final String DIC_LABEL_DEFAULT_ROLE_ID = "default_role_id";
    public static final String DIC_LABEL_DEFAULT_DEPT_ID = "default_dept_id";

    public static final String DIC_LABEL_STAFF_ROLE_ID = "staff_role_id";


    @Autowired
    private ISysUserService userService;
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private SysDictDataMapper dictDataMapper;
    @Autowired
    private ISysAgentService agentService;
    @Autowired
    private IStationService stationService;
    @Autowired
    private StaffMapper staffMapper;

    @Override
    public List<StaffVO> queryStaffList(StaffVO form) {
//        SysUser sysUser = StaffVO.toSysUser(form);
//        sysUser.getParams().put(Constants.PARAMS_ORDER_KEY,"order by u.user_id desc");
//        List<SysUser> list = userService.selectUserList(sysUser);
//        return list.stream().map(StaffVO::of).collect(Collectors.toList());
        String roleId = dictDataMapper.selectDictValue(DIC_TYPE_STAFF_SETTING, DIC_LABEL_STAFF_ROLE_ID);
        startPage();
        List<StaffVO> staffVOS = staffMapper.queryStaffList(form, Integer.parseInt(roleId));
        for (StaffVO vo : staffVOS) {
            if (StringUtils.isNotBlank(vo.getGun())) {
                String[] split = vo.getGun().split(",");
                List<String> longs = Arrays.stream(split).map(Long::parseLong)
                        .sorted().map(String::valueOf).collect(Collectors.toList());
                vo.setGunList(longs);
            }else{
                vo.setGunList(Collections.emptyList());
            }
        }
        PageHelper.clearPage();
        return staffVOS;
    }

    public long countStaffNum(StaffVO form){
        String roleId = dictDataMapper.selectDictValue(DIC_TYPE_STAFF_SETTING, DIC_LABEL_STAFF_ROLE_ID);
        Page<?> page = PageHelper.startPage(1, -1, true);
        staffMapper.queryStaffList(form, Integer.parseInt(roleId));
        PageHelper.clearPage();
        return page.getTotal();
    }

    @Override
    public int insertStaff(StaffVO staff) {
        SysUser user = StaffVO.toSysUser(staff);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null) {
            throw new CustomException(ErrorCode.SYS_NO_LOGIN);
        }
        Long stationId = user.getStationId();
        stationId = stationId == null ? loginUser.getUser().getStationId() : stationId;
        if (stationId == null) {
            throw new CustomException(ErrorCode.VALIDATE_ERROR);
        }
        Station station = stationService.selectStationById(stationId);
        if (station == null) {
            throw new CustomException(ErrorCode.STATION_NOT_FOUND);
        }
        user.setStationId(station.getStationId());
        user.setEnterpriseId(station.getEnterpriseId());
        if(StringUtils.isBlank(user.getPassword())){
            throw new CustomException(ErrorCode.VALIDATE_ERROR);
        }
        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName()))){
            throw new CustomException(ErrorCode.USER_REPEAT_USERNAME);
        }
        if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))){
            throw new CustomException(ErrorCode.USER_REPEAT_PHONENUMBER);
        }
        String roleId = dictDataMapper.selectDictValue(DIC_TYPE_STAFF_SETTING, DIC_LABEL_DEFAULT_ROLE_ID);
        String deptId = dictDataMapper.selectDictValue(DIC_TYPE_STAFF_SETTING, DIC_LABEL_DEFAULT_DEPT_ID);
        if (StringUtils.isNotBlank(roleId)) {
            String[] ids = roleId.split(",");
            Long[] roleIds = new Long[ids.length];
            for (int i = 0; i < ids.length; i++) {
                roleIds[i] = Long.parseLong(ids[i]);
            }
            user.setRoleIds(roleIds);
        }
        if (StringUtils.isNotBlank(deptId)) {
            user.setDeptId(Long.parseLong(deptId));
        }
        user.setUserLevel(UserConstants.LEVEL_THREE);
        user.setCreateBy(SecurityUtils.getUsername());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        if(user.getStationId()!=null){
            redisCache.deleteObject("push:emplist:"+user.getStationId());
        }
        return userService.insertUser(user);
    }

    @Override
    public int updateStaff(StaffVO staff) {
        SysUser user = StaffVO.toSysUser(staff);
        SysUser oldUser = userService.selectUserById(user.getUserId());
        if (oldUser == null) {
            throw new CustomException(ErrorCode.VALIDATE_ERROR);
        }
        if(!StringUtils.equals(oldUser.getUserName(),user.getUserName())){
            if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName()))){
                throw new CustomException(ErrorCode.USER_REPEAT_USERNAME);
            }
        }
        if (!StringUtils.equals(oldUser.getPhonenumber(), user.getPhonenumber())) {
            if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))){
                throw new CustomException(ErrorCode.USER_REPEAT_PHONENUMBER);
            }
        }
        if(!Objects.equals(oldUser.getStationId(),user.getStationId())){
            Station station = stationService.selectStationById(user.getStationId());
            if (station == null) {
                throw new CustomException(ErrorCode.STATION_NOT_FOUND);
            }
            user.setEnterpriseId(station.getEnterpriseId());
        }
        String password = user.getPassword();
        if(StringUtils.isNotBlank(password)){
            user.setPassword(SecurityUtils.encryptPassword(password));
        }
        user.setUserLevel(UserConstants.LEVEL_THREE);
        int i = userMapper.updateUser(user);
        deleteRedisCache(user);
        return i;
    }

    @Override
    public StaffVO getById(Long id) {
        SysUser sysUser = userService.selectUserById(id);
        return StaffVO.of(sysUser);
    }

    @Override
    @Transactional
    public boolean deleteStaffByIds(Long[] ids) {
        int i = userService.deleteUserByIds(ids);
        for(Long id :ids){
            SysAgent sysAgent =new SysAgent();
            sysAgent.setUserId(id);
            agentService.deleteSysAgent(sysAgent);
            deleteUserCache(id);
        }
        return i>0;
    }

    @Override
    public List<GunVo> queryStationGunList(Long stationId) {
        List<StationOillGun> stationOillGuns = staffMapper.queryStationGunList(stationId);
        List<GunVo> gunVos = new ArrayList<>();
        for (StationOillGun oilGun : stationOillGuns) {
            String names = oilGun.getGunName();
            String[] split = names.split(",");
            for (String s : split) {
                if (StringUtils.isNumeric(s)) {
                    GunVo gunVo = new GunVo();
                    gunVo.setGunName(Integer.parseInt(s));
                    gunVo.setStationId(stationId);
                    gunVo.setOil(oilGun.getOil());
                    gunVos.add(gunVo);
                }
            }
        }
        gunVos.sort(Comparator.comparingInt(GunVo::getGunName));
        return gunVos;
    }

    @Override
    public int getUserPermissions(Long userId) {
        //0admin 1油企 2油站 3员工 5区域经理 6业务员
        SysUser sysUser = userService.selectUserById(userId);
        if (null == sysUser.getUserLevel() || sysUser.getUserLevel().equals("0")) return 0;
        if (sysUser.getUserLevel().equals("2")){
            for (SysRole role : sysUser.getRoles()) {
                String roleName = role.getRoleName();
                if (roleName.equals("员工")) return  3;
            }
            return 2;
        }
        if (sysUser.getUserLevel().equals("1")) return 1;
        if (sysUser.getUserLevel().equals("3")) return 3;
        if (sysUser.getUserLevel().equals("5")) return 5;
        if (sysUser.getUserLevel().equals("6")) return 6;

        return 0;
    }

    private void deleteUserCache(Long userId){
        redisCache.deleteObject("userid:"+userId);
    }

    private void deleteRedisCache(SysUser user){
        deleteUserCache(user.getUserId());
        redisCache.deleteObject("push:emplist:"+user.getStationId());
        redisCache.deleteObject( "price:"+ user.getStationId()+":"+user.getUserId() );
    }

    private void startPage(){
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        if (!Objects.isNull(pageNum) && !Objects.isNull(pageSize)) {
            String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
            PageHelper.startPage(pageNum, pageSize, orderBy);
        }
    }

}
